
def to_string(ir)
  opcode = get_opcode(ir)
  case(opcode)
  when $OP[:LI]
    "%-8s $#{get_rd(ir)},  #{get_imm(8,ir)}" % [$T[opcode]]
  when $OP[:LEA]
    "%-8s $#{get_rd(ir)},  #{get_imm(8,ir)}" % [$T[opcode]]
  when $OP[:SW]
    "%-8s $#{get_rd(ir)},  $#{get_rs(ir)},  #{get_imm(5,ir)<<1}" % [$T[opcode]]
  when $OP[:LW]
    "%-8s $#{get_rd(ir)},  $#{get_rs(ir)},  #{get_imm(5,ir)<<1}" % [$T[opcode]]
  when $OP[:SB]
    "%-8s $#{get_rd(ir)},  $#{get_rs(ir)},  #{get_imm(5,ir)}" % [$T[opcode]]
  when $OP[:LB]
    "%-8s $#{get_rd(ir)},  $#{get_rs(ir)},  #{get_imm(5,ir)}" % [$T[opcode]]
  else

    "%-8s $#{get_rd(ir)},  $#{get_rs(ir)},  $#{get_rt(ir)}" % [$T[opcode]]
  end
end


def read_mem(addr)
  #puts addr
  ($MEM[(addr+1)&0x0000FFFF] << 8) | ($MEM[addr&0x0000FFFF])
end

def get_opcode(ir)
  (ir >> 11) & 0x001F
end

def get_rd(ir)
  (ir >> 8) & 0x0007
end

def get_rs(ir)
  (ir >> 5) & 0x0007
end

def get_rt(ir)
  (ir >> 2) & 0x0007
end

def get_imm(bits,ir)
  r = ir & (2**bits - 1)
  if ir[bits-1] == 1
    r |= ~(2**bits - 1)
  end
  return r
end


$OP = {}
$T = {}
op_file = File.open("OPCODE.txt","r")
while line = op_file.gets
  /(?<num>\d+)\s+(?<mne>\w+)/ =~ line
  $OP[mne.to_sym] = num.to_i
  $T[num.to_i] = mne.to_sym
end

$MEM = {}
mif_file = File.open(ARGV[0],"r")
while !(/CONTENT BEGIN/ === line = mif_file.gets) 
  puts line
end
line = mif_file.gets
while (line != nil) && !(/END;/ === line)
  /(?<addr>\w+)\s*:\s*(?<val>\w+)/ =~ line
  if(addr != nil && val != nil)
    $MEM[addr.hex] = val.hex
  else
    /\[(?<addr1>\w+)\.\.(?<addr2>\w+)\]\s*:\s*(?<val1>\w+)/ =~ line
    (addr1.hex..addr2.hex).each{|a| $MEM[a] = val1.hex}
  end
  line = mif_file.gets
end

o = File.new(ARGV[0].sub(/\.mif/,".txt"),"w")

$MEM.each do |a,m|
  if a.even?
    ir = read_mem(a)
    o.puts "%04x : \t#{to_string(ir)}" % [a]
  end
end

